package com.ares.basic.utils;

import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName:TimeUtils
 * @Author:zhangdaqing
 * @Date 19:18 2019/5/6 0006
 * @Description: 各种时间，日期工具方法
 */
public class TimeUtils {

    private static final SimpleDateFormat DATE_HM_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    private static final SimpleDateFormat DATE_HMS_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final SimpleDateFormat DATE_YMD_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat DATE_YM_FORMAT = new SimpleDateFormat("yyyy-MM");
    private static final SimpleDateFormat DATE_MD_FORMAT = new SimpleDateFormat("MM-dd");
    private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss");
    private static final SimpleDateFormat DATE_YMDHM_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");
    private static final SimpleDateFormat DATE_YMD_LINE_FORMAT = new SimpleDateFormat("yyyyMMdd");
    private static final SimpleDateFormat DATE_YMD_DIA_FORMAT = new SimpleDateFormat("yyyy/MM/dd");

    public static final int SECONDS_IN_DAY = 60 * 60 * 24;
    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;

    /**
     * 根据时间获取当前日期+时间的毫秒时间戳
     * 不传time则返回当前毫秒时间戳
     *
     * @param time 时:分:秒，如：10:10:00
     * @return
     */
    public static Long currentTime(String time) {
        try {
            if (StringUtils.isBlank(time)) {
                // 不传返回当前时间戳毫秒，增加方法通用性
                return LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            }
            LocalDate localDate = LocalDate.now();
            String s = localDate + " " + time;
            DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime parse = LocalDateTime.parse(s, ftf);
            // 东8区，也就是北京时间，避免操作系统时区错误导致误差
            Long currentTimes = LocalDateTime.from(parse).toInstant(ZoneOffset.of("+8")).toEpochMilli();
            return currentTimes;

        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 根据时间获取毫秒时间戳
     * 不传time则返回当前毫秒时间戳
     *
     * @param time 时:分:秒，如：10:10:00
     * @return
     */
    public static Long getCurrentTimeByTime(String time) {
        try {
            if (StringUtils.isBlank(time)) {
                // 不传返回当前时间戳毫秒，增加方法通用性
                return LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            }
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = format.parse(time);
            Long timestamp = date.getTime();
            return timestamp;
        } catch (Exception e) {

            return null;
        }
    }

    /**
     * 　　* @Author : zhangdaqing
     * 　　* @Date :  2019/6/22 0022
     *
     * @Description : 根据传来的毫秒数，截取成时间 12:30:56
     */
    public static String getTimeStr(Long milliseconds) {
        String time = null;
        if (milliseconds != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(milliseconds);
            int hour = calendar.get(Calendar.HOUR_OF_DAY);//24小时制
            int minute = calendar.get(Calendar.MINUTE);
            int second = calendar.get(Calendar.SECOND);
            time = hour + ":" + minute + ":" + second;
        }
        return time;
    }

    public enum DateFmt {
        DATE_HM_FORMAT,
        DATE_HMS_FORMAT,
        DATE_YMD_FORMAT,
        DATE_YM_FORMAT,
        DATE_MD_FORMAT,
        TIME_FORMAT,
        DATE_YMDHM_FORMAT,
        DATE_YMD_LINE_FORMAT,
        DATE_YMD_DIA_FORMAT
    }

    /**
     * 格式化Date成字符串
     *
     * @param date
     * @param dateFmt
     * @return
     */
    public static String formatToStr(Date date, DateFmt dateFmt) {
        if (date == null) {
            return "";
        }
        if (dateFmt == DateFmt.DATE_HM_FORMAT) {
            return DATE_HM_FORMAT.format(date);
        } else if (dateFmt == DateFmt.DATE_HMS_FORMAT) {
            return DATE_HMS_FORMAT.format(date);
        } else if (dateFmt == DateFmt.DATE_YMD_FORMAT) {
            return DATE_YMD_FORMAT.format(date);
        } else if (dateFmt == DateFmt.DATE_YM_FORMAT) {
            return DATE_YM_FORMAT.format(date);
        } else if (dateFmt == DateFmt.DATE_MD_FORMAT) {
            return DATE_MD_FORMAT.format(date);
        } else if (dateFmt == DateFmt.TIME_FORMAT) {
            return TIME_FORMAT.format(date);
        } else if (dateFmt == DateFmt.DATE_YMDHM_FORMAT) {
            return DATE_YMDHM_FORMAT.format(date);
        }else if (dateFmt == DateFmt.DATE_YMD_DIA_FORMAT) {
            return DATE_YMD_DIA_FORMAT.format(date);
        } else {
            return DATE_HMS_FORMAT.format(date);
        }
    }

    /**
     * 格式化字符串成Date类型
     *
     * @param dateFmt
     * @return
     */
    public static Date formatToDate(String str, DateFmt dateFmt) {
        try {
            if (dateFmt == DateFmt.DATE_HM_FORMAT) {
                return DATE_HM_FORMAT.parse(str);
            } else if (dateFmt == DateFmt.DATE_HMS_FORMAT) {
                return DATE_HMS_FORMAT.parse(str);
            } else if (dateFmt == DateFmt.DATE_YMD_FORMAT) {
                return DATE_YMD_FORMAT.parse(str);
            } else if (dateFmt == DateFmt.DATE_YM_FORMAT) {
                return DATE_YM_FORMAT.parse(str);
            } else if (dateFmt == DateFmt.DATE_MD_FORMAT) {
                return DATE_MD_FORMAT.parse(str);
            } else if (dateFmt == DateFmt.TIME_FORMAT) {
                return TIME_FORMAT.parse(str);
            }else if (dateFmt == DateFmt.DATE_YMD_DIA_FORMAT) {
                return DATE_YMD_DIA_FORMAT.parse(str);
            } else {
                return DATE_HMS_FORMAT.parse(str);
            }
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 得到两个日期之间的天数
     *
     * @param saleDate   开始时间
     * @param untillDate 结束时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date saleDate, Date untillDate) throws ParseException {
        saleDate = DATE_YMD_FORMAT.parse(DATE_YMD_FORMAT.format(saleDate));
        untillDate = DATE_YMD_FORMAT.parse(DATE_YMD_FORMAT.format(untillDate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(saleDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(untillDate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 输入一个日期以字符串形式返回该日期的“field”部分
     *
     * @param date
     * @return 字符串
     */
    public static String getDateTime(Date date, String field) {

        String res = null;

        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setTime(date);
        if (field.equalsIgnoreCase("YEAR"))
            return "" + calendar.get(Calendar.YEAR);
        else if (field.equalsIgnoreCase("MONTH"))
            return "" + (calendar.get(Calendar.MONTH) + 1);
        else if (field.equalsIgnoreCase("WEEKOFMONTH"))
            return "" + calendar.get(Calendar.WEEK_OF_MONTH);
        else if (field.equalsIgnoreCase("WEEKOFYEAR"))
            return "" + calendar.get(Calendar.WEEK_OF_YEAR);
        else if (field.equalsIgnoreCase("DAY"))
            return "" + calendar.get(Calendar.DATE);
        return res;
    }

    /**
     * 获取某天零点时间
     *
     * @param date
     * @return
     */
    public static Date getStartDate(Date date) {
        Calendar day = Calendar.getInstance();
        day.setTime(date);
        day.set(Calendar.HOUR_OF_DAY, 0);
        day.set(Calendar.MINUTE, 0);
        day.set(Calendar.SECOND, 0);
        day.set(Calendar.MILLISECOND, 0);

        return day.getTime();
    }

    /**
     * 获取某天结束时间
     *
     * @param date
     * @return
     */
    public static Date getEndDate(Date date) {
        Calendar day = Calendar.getInstance();
        day.setTime(date);
        day.set(Calendar.HOUR_OF_DAY, 23);
        day.set(Calendar.MINUTE, 59);
        day.set(Calendar.SECOND, 59);
        day.set(Calendar.MILLISECOND, 999);
        return day.getTime();
    }

    /**
     * 获取某天结束时间
     *
     * @param date
     * @return
     */
    public static Date getYesterday(Date date) {
        Calendar day = Calendar.getInstance();
        day.setTime(date);
        day.add(Calendar.DAY_OF_YEAR, -1);
        return day.getTime();
    }

    /**
     * 获取某天结束时间
     *
     * @param date
     * @return
     */
    public static Date getTomorrow(Date date) {
        Calendar day = Calendar.getInstance();
        day.setTime(date);
        day.add(Calendar.DAY_OF_YEAR, 1);
        return day.getTime();
    }

    /**
     * 得到输入的时间所在的周的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar b = Calendar.getInstance();
        b.setTime(date);
        int sub = 1;
        if (b.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { // 除了U.S，基本以礼拜一为一周开始
            b.set(Calendar.WEEK_OF_MONTH, b.get(Calendar.WEEK_OF_MONTH) - 1);
            sub = 2;
        }
        if (b.get(Calendar.DAY_OF_WEEK) == 2) {
            b.set(Calendar.WEEK_OF_MONTH, b.get(Calendar.WEEK_OF_MONTH) - sub); // 范围设置为上个星期

            b.set(Calendar.HOUR_OF_DAY, 0);
            b.set(Calendar.MINUTE, 0);
            b.set(Calendar.SECOND, 0);
            b.set(Calendar.MILLISECOND, 0);
            b.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        } else {
            b.set(Calendar.DAY_OF_WEEK, 2);
            b.set(Calendar.HOUR_OF_DAY, 0);
            b.set(Calendar.MINUTE, 0);
            b.set(Calendar.SECOND, 0);
            b.set(Calendar.MILLISECOND, 0);
        }

        return b.getTime();
    }

    /**
     * 得到输入时间的上周环比时间点
     *
     * @param date
     * @return
     */
    public static Map<String, Date> getPreWeekChain(Date date) {
        Date beginTime = new Date(date.getTime());
        Date endTime = new Date(date.getTime());
        Calendar b = Calendar.getInstance();
        Calendar e = Calendar.getInstance();
        b.setTime(beginTime);
        e.setTime(endTime);
        int sub = 1;
        if (b.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { // 除了U.S，基本以礼拜一为一周开始
            b.set(Calendar.WEEK_OF_MONTH, b.get(Calendar.WEEK_OF_MONTH) - 1);
            sub = 2;
        }

        if (b.get(Calendar.DAY_OF_WEEK) == 2) {
            b.set(Calendar.WEEK_OF_MONTH, b.get(Calendar.WEEK_OF_MONTH) - sub - 1); // 范围设置为上上个星期
            e.set(Calendar.WEEK_OF_MONTH, e.get(Calendar.WEEK_OF_MONTH) - 1 - 1); // 范围设置为上上个星期
        } else {
            b.set(Calendar.WEEK_OF_MONTH, b.get(Calendar.WEEK_OF_MONTH) - sub); // 范围设置为上个星期
            e.set(Calendar.WEEK_OF_MONTH, e.get(Calendar.WEEK_OF_MONTH) - 1); // 范围设置为上个星期
        }

        b.set(Calendar.HOUR_OF_DAY, 0);
        b.set(Calendar.MINUTE, 0);
        b.set(Calendar.SECOND, 0);
        b.set(Calendar.MILLISECOND, 0);
        b.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        beginTime = b.getTime();
        endTime = e.getTime();

        Map<String, Date> map = new HashMap<>();
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);

        return map;
    }

    /**
     * sql时间戳转换为字符串
     *
     * @param time
     * @param fmt
     * @return
     */
    public static String timestampToStr(Timestamp time, DateFmt fmt) {
        try {
            Date date = null;
            if (null != time) {
                date = new Date(time.getTime());
            }
            return formatToStr(date, fmt);

        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 毫秒时间戳转化为时间字符串
     *
     * @param time
     * @param fmt
     * @return
     */
    public static String timestampToStr(long time, DateFmt fmt) {
        try {
            Date date = new Date(time);
            return formatToStr(date, fmt);

        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 获取当前时间戳，精确到秒
     */
    public static Long currentSecondTime() {
        return System.currentTimeMillis() / 1000;
    }


    /**
     * 获取本月开始一刻的时间戳
     */
    public static Long monthStartTimeInMillis() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    private static long toDay(long millis) {
        return (millis + TimeZone.getTimeZone(ZoneOffset.of("+8")).getOffset(millis)) / MILLIS_IN_DAY;
    }

    /**
     * 判断两个时间戳是否是同一天
     * 单位 毫秒
     */
    public static boolean isSegamentTimeInSameDay(long startTime, long endTime) {
        final long interval = endTime - startTime;
        return interval < MILLIS_IN_DAY
                && interval > -1L * MILLIS_IN_DAY
                && toDay(endTime) == toDay(startTime);
    }


    /**
     * 根据一个时间戳，判断当前时间戳是否是今天
     */
    public static boolean isToday(Long millis) {
        Date date = new Date(millis);
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        if (fmt.format(date).toString().equals(fmt.format(new Date()).toString())) {//格式化为相同格式
            return true;
        } else {
            return false;
        }
    }

    //根据当前时间获取前一天的日期 yyyy-MM-dd
    public static String getYesterdayDate(Long millis) {
        String yesterdayDate = "";
        if (millis != null) {
            long yesterdayDateMillis = millis.longValue() - 24 * 60 * 60 * 1000;
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(yesterdayDateMillis);
            Date date = c.getTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            yesterdayDate = sdf.format(date);
        }
        return yesterdayDate;
    }

    /**
     * 　　* @Author : zhangdaqing
     * 　　* @Date :  2019/7/5 0005
     *
     * @Description : 毫秒转日期和时间
     */
    public static String getDateTimeByMiles(Long miles) {
        String time = "";
        ZoneId zoneId = ZoneOffset.systemDefault();
        //之所以这么初始化，是因为根据传入的时间进行操作
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(miles / 1000), zoneId);
        DateTimeFormatter sf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        time = sf.format(localDateTime);
        return time;
    }

    /**
     * 通过时间戳获取年月
     *
     * @param miles
     * @return
     */
    public static String getYearAndMonthDateTimeByMiles(Long miles) {
        String time = "";
        ZoneId zoneId = ZoneOffset.systemDefault();
        //之所以这么初始化，是因为根据传入的时间进行操作
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(miles / 1000), zoneId);
        DateTimeFormatter sf = DateTimeFormatter.ofPattern("yyyy-MM");
        time = sf.format(localDateTime);
        return time;
    }

    /**
     * 获取当前年份的开始时间戳
     */
    public static Long getCurrYearStartMiles() {

        return yearTimeInMillis();
    }

    // 获取当年0点时间戳
    private static Long yearTimeInMillis() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取当前月份的开始时间戳
     */
    public static Long getCurrMonthStartMills() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取当前月最后一天时间戳
     */
    public static Long getCurrMonthEndMills() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取当日今日零点
     * cxt
     */
    public static Long getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        Long time = todayStart.getTimeInMillis();
        return time;
    }

    /**
     * 获取几天前或者几天后的零点
     * cxt
     */
    public static Long getStartTime(Integer day) {
        Long time = getStartTime();
        time = time + day * 86400000l;
        return time;
    }

    /**
     * 获取当前时间前一天或后一天的时间戳
     *
     * @param day
     * @return
     */
    public static Long getArbitraryNowTime(Integer day) {
        Long time = System.currentTimeMillis();
        time = time + day * 86400000l;
        return time;
    }

    /**
     * 获取指定时间零点
     * cxt
     */
    public static Long getStartTime(Date date) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        Long time = todayStart.getTimeInMillis();
        return time;
    }

    /**
     * 获取指定时间23点
     * cxt
     */
    public static Long getEndTime(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(date);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        Long time = todayEnd.getTimeInMillis();
        return time;
    }

    /**
     * 获取几天前或者几天后的最后的23:59:59
     * cxt
     */
    public static Long getEndTime(Integer day) {
        Long time = getnowEndTime();
        time = time + day * 86400000l;
        return time;
    }

    /**
     * 获取几天前或者几天后的最后的23:59:59
     * cxt
     */
    public static Long startEndTime(Integer day) {
        Long time = getstartEndTime();
        time = time + day * 86400000l;
        return time;
    }

    /**
     * 获取当日23点
     * cxt
     */
    public static Long getnowEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        Long time = todayEnd.getTimeInMillis();
        return time;
    }

    /**
     * 今日开始时间
     */
    public static Long getstartEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 0);
        todayEnd.set(Calendar.MINUTE, 00);
        todayEnd.set(Calendar.SECOND, 00);
        todayEnd.set(Calendar.MILLISECOND, 000);
        Long time = todayEnd.getTimeInMillis();
        return time;
    }

    /**
     * 获取上个月的开始时间戳
     */
    public static Long getCurrLastMonthStartMills(Date date) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, -1);//设置到上个月
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取上个月的结束时间戳
     */
    public static Long getCurrLastMonthEndMills(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        int MaxDay = calendar.getMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), MaxDay, 23, 59, 59);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 根据传入时间找到下个月时间
     */
    public static Long getCurrLastMonthEndMillsAdd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, +1);
        // int MaxDay=calendar.getMaximum(Calendar.DAY_OF_MONTH);
        // calendar.set( calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 根据传入时间找到明年时间
     */
    public static Long getCurrLastMonthEndMillsAdds(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, +1);
        // int MaxDay=calendar.getMaximum(Calendar.DAY_OF_MONTH);
        // calendar.set( calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));
        Long time = calendar.getTimeInMillis();
        return time;
    }


    /**
     * 获取本月开始时间戳
     */
    public static Long getCurrLastMonthStartMill(Date date) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);//设置本月
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取本月的结束时间戳(正确)
     */
    public static Long getCurrLastAddMonthStartMill(Date date) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 1);//设置本月
        calendar.set(Calendar.DAY_OF_MONTH, 0);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis() + 60 * 60 * 24 * 1000;
        return time;
    }

    /**
     * 根据现在时间，得到2天前的时间
     */
    public static Long GetYesterdayTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前日期
        Date today = new Date();
        // 根据当前日期获取昨天的当前日期
        Date yesterday = new Date(new Date().getTime() - 172800000L);
        return yesterday.getTime();
    }

    /**
     * 获取本月的结束时间戳(错误)
     */
    public static Long getCurrLastMonthEndMill(Date date) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Long time = calendar.getTimeInMillis() + 24 * 60 * 60 * 1000;
        return time;

//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar.add(Calendar.MONTH, 0);
//        int MaxDay=calendar.getMaximum(Calendar.DAY_OF_MONTH);
//        calendar.set( calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), MaxDay, 23, 59, 59);
//        Long time = calendar.getTimeInMillis();
//        return time;
    }

    /**
     * 获取指定日期所在月份开始的时间戳
     *
     * @param date 指定日期
     * @return
     */
    public static Long getMonthBegin(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND, 0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);
        // 获取本月第一天的时间戳
        return c.getTimeInMillis();
    }

    /**
     * 获取指定日期所在月份结束的时间戳
     *
     * @param date 指定日期
     * @return
     */
    public static Long getMonthEnd(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c.set(Calendar.MINUTE, 59);
        //将秒至59
        c.set(Calendar.SECOND, 59);
        //将毫秒至999
        c.set(Calendar.MILLISECOND, 999);
        // 获取本月最后一天的时间戳
        return c.getTimeInMillis();
    }

    public static String getDateStr(long timeInMillis) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(timeInMillis);
        Date date = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }

    /**
     * 时间格式转成时间戳
     *
     * @param time
     * @param dateFmt
     * @return
     */
    public static Long formatToLong(String time, DateFmt dateFmt) {
        try {
            if (StringUtils.isBlank(time)) {
                return 0L;
            }
            if (dateFmt == DateFmt.DATE_HM_FORMAT) {
                return DATE_HM_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_HMS_FORMAT) {
                return DATE_HMS_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_YMD_FORMAT) {
                return DATE_YMD_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_YM_FORMAT) {
                return DATE_YM_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_MD_FORMAT) {
                return DATE_MD_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.TIME_FORMAT) {
                return TIME_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_YMDHM_FORMAT) {
                return DATE_YMDHM_FORMAT.parse(time).getTime();
            } else if (dateFmt == DateFmt.DATE_YMD_LINE_FORMAT) {
                return DATE_YMD_LINE_FORMAT.parse(time).getTime();
            }else if (dateFmt == DateFmt.DATE_YMD_DIA_FORMAT) {
                return DATE_YMD_DIA_FORMAT.parse(time).getTime();
            } else {
                return DATE_HMS_FORMAT.parse(time).getTime();
            }
        } catch (Exception e) {

        }
        return 0L;
    }

    /**
     * 获取当年的开始时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @return
     */
    public static Long getLastYearStartTime(Long timeStamp) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeInMillis(timeStamp);
        calendar.add(Calendar.YEAR, -1);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当年的最后时间戳
     *
     * @param timeStamp 毫秒级时间戳
     * @return
     */
    public static Long getLastYearEndTime(Long timeStamp) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeInMillis(timeStamp);
        int year = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, year - 1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTimeInMillis();
    }

    public static Long getSixOneTime(Long timeStamp) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeInMillis(timeStamp);
        int year = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, 5);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTimeInMillis();
    }


    /**
     * 获取当前时间在本月的第几天
     *
     * @return
     */
    public static Integer getThisDay() {
        SimpleDateFormat format = new SimpleDateFormat("dd");
        String day = format.format(new Date());
        Integer dayInt = Integer.parseInt(day);
        return dayInt;
    }

    /**
     * 根据传入的月数获取前几个月或者后几个月的开始时间戳
     *
     * @param months 月数
     * @return
     */
    public static Long monthStartTimeByAround(Integer months) {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTime(new Date());
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, months);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }



    /**
     * 返回当前时间在今日的第几个小时
     * @return
     */
    public static Integer checkHour() {
        SimpleDateFormat format = new SimpleDateFormat("HH");
        String day = format.format(new Date());
        Integer hour = Integer.parseInt(day);
        return hour;
    }

    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);  //当前年份
        int monthNow = cal.get(Calendar.MONTH);  //当前月份
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
        cal.setTime(birthDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        int age = yearNow - yearBirth;   //计算整岁数
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
            } else {
                age--;//当前月份在生日之前，年龄减一
            }
        }
        return age;
    }

    /**
     * 校验日期格式:yyyy-MM-dd
     *
     * @param time
     * @return
     */
    public static boolean checkTimeByYmd(String time) {
        if (time.length() != 10) {
            return false;
        }
        Pattern pattern = Pattern.compile("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|\n" +
                "((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|\n" +
                "((0[48]|[2468][048]|[3579][26])00))-02-29)$");
        Matcher matcher = pattern.matcher(time);
        return matcher.find();
    }

}
